﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using log4net;
using log4net.Config;
using log4net.Appender;
using log4net.Repository.Hierarchy;

namespace Logger
{
    public enum Level { Debug, Info, Warning, Error, Fatal }

    public static class Logger
    {
        private static bool _isInitialized;
        private static string _name;

        //public
        public static void Initialise(string filePath, string name)
        {
            if (!_isInitialized)
            {
                _name = name;
                if (!String.IsNullOrEmpty(filePath))
                    XmlConfigurator.ConfigureAndWatch(new FileInfo(filePath));
                else
                    XmlConfigurator.Configure();
                _isInitialized = true;
            }
        }

        public static bool Log(Level level, string message, Exception exception)
        {
           
            return Log(level, "NA", "NA", message, exception);
        }

        public static bool Log(Level level, string Id, string Config, string message, Exception exception)
        {
            var log = LogManager.GetLogger(_name);
            if (log != null && IsEnabled(log, level))
            {
                var info = string.Format("{0}@{1}@{2}", Id ?? "NA", Config ?? "NA", message);

                switch (level)
                {
                    case Level.Debug: log.Debug(info, exception); break;
                    case Level.Info: log.Info(info, exception); break;
                    case Level.Warning: log.Warn(info, exception); break;
                    case Level.Error: log.Error(info, exception); break;
                    case Level.Fatal: log.Fatal(info, exception); break;
                }
            }

            return false;
        }

        public static bool Log(Level level, string message)
        {
            ILog log = LogManager.GetLogger(_name);
            if (log != null && IsEnabled(log, level))
            {
                var info = string.Format("NA@NA@{0}", message);

                switch (level)
                {
                    case Level.Debug: log.Debug(info); break;
                    case Level.Info: log.Info(info); break;
                    case Level.Warning: log.Warn(info); break;
                    case Level.Error: log.Error(info); break;
                    case Level.Fatal: log.Fatal(info); break;
                }
            }
            
            return false;
        }

        public static string FilePath()
        {
            var rootAppender = ((Hierarchy)LogManager.GetRepository()).Root.Appenders.OfType<FileAppender>().FirstOrDefault();
            return rootAppender != null ? rootAppender.File : string.Empty;
        }

        //private
        private static bool IsEnabled(ILog log, Level level)
        {
            switch (level)
            {
                case Level.Debug: return log.IsDebugEnabled;
                case Level.Info: return log.IsInfoEnabled;
                case Level.Warning: return log.IsWarnEnabled;
                case Level.Error: return log.IsErrorEnabled;
                case Level.Fatal: return log.IsFatalEnabled;
                default: return false;
            }
        }
    }
}

